package threadPoolExecutorTest;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/***
 * corePoolSize

核心线程数，默认情况下核心线程会一直存活，即使处于闲置状态也不会受存keepAliveTime限制。除非将allowCoreThreadTimeOut设置为true。

maximumPoolSize

线程池所能容纳的最大线程数。超过这个数的线程将被阻塞。当任务队列为没有设置大小的LinkedBlockingDeque时，这个值无效。

keepAliveTime

非核心线程的闲置超时时间，超过这个时间就会被回收。

unit

指定keepAliveTime的单位，如TimeUnit.SECONDS。当将allowCoreThreadTimeOut设置为true时对corePoolSize生效。

workQueue

线程池中的任务队列.

常用的有三种队列，SynchronousQueue,LinkedBlockingDeque,ArrayBlockingQueue。

threadFactory

线程工厂，提供创建新线程的功能。ThreadFactory是一个接口，只有一个方法
 * @author glodon
 *
 */

public class ThreadPoolExecutorTest {
	
	
	
	
	public static void main(String[] args) throws InterruptedException {

		// SynchronousQueue  1: 當超過核心線程數時小於最大線程數時，會創建和請求的線程數一樣多的線程，一部分是核心線程，多餘一部分是非核心線程，會在處於閒置狀態下一定時間
		// 被回收 ，如果再有線程來，會用核心線程池裡的線程去處理，核心線程數不夠 ，再創建新的非核心線程去處理，處理完閒置到一定時間，被回收，閒置過期時間可以設置
		//test1();
		
		//LinkedBlockingDeque 如果线程数量>核心线程数，但<=最大线程数，并且任务队列是LinkedBlockingDeque的时候，並且LinkedBlockingDeque 
		//不限制大小時超过核心线程数量的任务会放在任务队列中排队。等核心線程處理完后，再用核心線程池裡的線程去處理隊列裡的線程
		test2();
		
		////如果线程数量>核心线程数，但<=最大线程数，并且任务队列是LinkedBlockingDeque的时候，並且LinkedBlockingDeque有限制大小時，
		//当LinkedBlockingDeque塞满时，新增的任务会直接创建新线程来执行，隊列裡塞滿的線程要等待核心線程去處理，当创建的线程数量超过最大线程数量时会抛异常。
		test2();
	
	}
	public static  void test2() throws InterruptedException{
		ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());	
Runnable myRunnable = Runn();	
		    executor.execute(myRunnable);
			executor.execute(myRunnable);
			executor.execute(myRunnable);
			executor.execute(myRunnable);
			System.out.println("队列任务数" + executor.getQueue().size());
			Thread.sleep(3000); 

			System.out.println("---先开三个---");
			System.out.println("核心线程数" + executor.getCorePoolSize());
			System.out.println("线程池数" + executor.getPoolSize());
			System.out.println("队列任务数" + executor.getQueue().size());
	}
	
	
	
	
	public static  void test1() throws InterruptedException{
		ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 5, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
		
		// 1: 當超過核心線程數時小於最大線程數時，會創建和請求的線程數一樣多的線程，一部分是核心線程，多餘一部分是非核心線程，會在處於閒置狀態下一定時間
		// 被回收 ，如果再有線程來，會用核心線程池裡的線程去處理，核心線程數不夠 ，再創建新的非核心線程去處理，處理完閒置到一定時間，被回收，閒置過期時間可以設置
		Runnable myRunnable = Runn();	
		
		executor.execute(myRunnable);
			executor.execute(myRunnable);
			executor.execute(myRunnable);
			Thread.sleep(3000);  //阻塞主線程后，再提交新的線程， 先用主線程裡的線程去執行，超過主線程里的，再啟動新的線程去執行，這個新啟動
			//的線程為非核心線程，會在設定的閒置時間后被回收
			executor.execute(myRunnable);
			executor.execute(myRunnable);
			executor.execute(myRunnable);
			executor.execute(myRunnable);
			System.out.println("---先开三个---");
			System.out.println("核心线程数" + executor.getCorePoolSize());
			System.out.println("线程池数" + executor.getPoolSize());
			System.out.println("队列任务数" + executor.getQueue().size());
		
	}
	
	
	
	
	
	
	
	
	
	
	public static Runnable Runn(){
		
		Runnable myRunnable = myRunnable = new Runnable() {
		    @Override
		    public void run() {
		        try {
		            Thread.sleep(1000);
		            System.out.println(Thread.currentThread().getName() + " run");
		        } catch (InterruptedException e) {
		            e.printStackTrace();
		        }

		    }
		};
		return myRunnable;
	}
	
	
	
	
}
